﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WordNet.Core
{
    /// <summary>
    /// Represents parts of speach objects
    /// </summary>
    public sealed class POS
    {
            public static readonly POS NOUN = new POS("noun", 'n', 1, "noun");
            public static readonly POS VERB = new POS("verb", 'v', 2, "verb");
            public static readonly POS ADJECTIVE = new POS("adjective", 'a', 3, "adj", "adjective");
            public static readonly POS ADVERB = new POS("adverb", 'r', 3, "adv", "adverb");
           
            // WordNet numbering scheme for parts of speech
            public const int NUM_NOUN                = 1;
            public const int NUM_VERB                = 2;
            public const int NUM_ADJECTIVE           = 3;
            public const int NUM_ADVERB              = 4;
            public const int NUM_ADJECTIVE_SATELLITE = 5;
            
            // character tag for parts of speach
            public const char TAG_NOUN                = 'n';
            public const char TAG_VERB                = 'v';
            public const char TAG_ADJECTIVE           = 'a';
            public const char TAG_ADVERB              = 'r';
            public const char TAG_ADJECTIVE_SATELLITE = 's';
        
            private string _name;
            private char _tag;
            private byte _num;
            private HashSet<string> _hint;
            
            private POS(string name, char tag, byte num, params string[] hint)
            {
                _name = name;
                _tag = tag;
                _num = num;
                _hint = new HashSet<string>( hint);
            }

            public string Name
            {
                get { return _name; }
            }

            public char Tag
            {
                get { return _tag; }
            }

            public byte Number
            {
                get { return _num; }
            }

            public HashSet<string> Hint
            {
                get { return _hint; }
            }

            public override String ToString()
            {
                return _name;
            }
           
           public static POS GetPartOfSpeech(DbPartOfSpeechType num)
           {
               switch (num)
               {
                   case ( DbPartOfSpeechType.Noun):
                       return NOUN;
                   case(DbPartOfSpeechType.Verb):
                       return VERB;
                   case DbPartOfSpeechType.Adv:
                       return ADVERB;
                   case DbPartOfSpeechType.AdjSat:
                   case DbPartOfSpeechType.Adj:
                       return ADJECTIVE;

                   default:
                       return null;
               }
           }

           public static POS GetPartOfSpeech(char tag)
           {
               switch (tag)
               {
                   case ('N'): // capital, fall through
                   case ('n'): return NOUN;
                   case ('V'): // capital, fall through
                   case ('v'): return VERB;
                   case ('R'): // capital, fall through
                   case ('r'): return ADVERB;
                   case ('s'): // special case, 's' for adjective satellite, fall through
                   case ('S'): // capital, fall through
                   case ('A'): // capital, fall through
                   case ('a'): return ADJECTIVE;
                   default:
                       return null;
               }
               
           }

           public static IEnumerable<POS> Values()
           {
               return new POS[] { NOUN, VERB, ADVERB, ADJECTIVE };
           }
    }
}
